<template>
  <div class="app-container">
    <ContentWrap style="padding: 0 !important;">
      <div style="width: 100%;" :style="getAvailableHeight">
        <L7Map @mapLoaded="handleMapLoaded" :zoom="13">

          <!-- 控制按钮面板 -->
          <div class="control-button-panel">
            <div class="custom-button-group-box">
              <div class="custom-button-box" @click="handleToolBarClick(1)">
                <el-tooltip content="清除工具" placement="top" effect="light">
                  <i class="el-icon-delete"></i>
                </el-tooltip>
              </div>
              <div class="custom-button-divider"></div>
              <div class="custom-button-box" @click="handleToolBarClick(2)">
                <el-tooltip content="分析工具" placement="top" effect="light">
                  <i class="el-icon-data-analysis"></i>
                </el-tooltip>
              </div>
              <div class="custom-button-divider"></div>
              <div class="custom-button-box" @click="handleToolBarClick(3)">
                <el-tooltip content="图例控制" placement="top" effect="light">
                  <i class="el-icon-s-flag"></i>
                </el-tooltip>
              </div>
              <div class="custom-button-divider"></div>
              <div class="custom-button-box" @click="handleToolBarClick(4)">
                <el-tooltip content="图层控制" placement="top" effect="light">
                  <i class="el-icon-copy-document"></i>
                </el-tooltip>
              </div>
            </div>
          </div>

          <!-- 图层控制面板 -->
          <div v-show="layerPanelVisible" class="analysis-layer-panel">
            <el-card style="min-width: 240px;max-width:300px;height: 100%;">
              <el-scrollbar style="height: 95%;">
                <el-tree :data="layerTreeData"
                         v-loading="layerTreeLoading"
                         show-checkbox
                         ref="refLayerTree"
                         node-key="name"
                         highlight-current
                         default-expand-all
                         :default-checked-keys="defaultCheckTreeData"
                         @check-change="handleNodeChange">
                  <template slot-scope="{ node, data }">
                    <div v-if="data.icon" style="display: flex;align-items: center;">
                      <img :src="getLayerNodeImage(data)" alt="" style="width: 16px;height: 16px;margin-right: 5px;">
                      <span style="font-size: 12px;">{{ data.name }}</span>
                      <span style="font-size: 12px;">{{ data.count ? `(${data.count})` : '' }}</span>
                    </div>
                    <div v-else>
                      <span style="font-size: 12px;">{{ data.name }}</span>
                      <span style="font-size: 12px;">{{ data.count ? `(${data.count})` : '' }}</span>
                    </div>
                  </template>
                </el-tree>
              </el-scrollbar>
            </el-card>
          </div>

          <!-- 分析工具面板 -->
          <div v-show="analysisToolPanelVisible" class="analysis-tool-panel">
            <div class="tool-box">
              <div class="tool-box-title">GIS分析</div>

              <div v-for="(item, index) in analysisToolOptions" :key="'item-'+index" class="tool-box-item">
                <div class="tool-box-item-title" :style="getActiveMainStyle(item.key)" @click="activeToolMain=item.key">
                  {{ item.name }}
                </div>

                <div class="tool-box-item-content" v-show="activeToolMain===item.key">
                  <div v-for="(subItem,subIndex) in item.tools" class="tool-box-item-tool"
                       :style="getActiveSubStyle(subItem.key)" @click="handleSubToolClick(subItem.key)">
                    {{ subItem.name }}
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 分析操作内容面板 -->
          <div class="analysis-content-panel" v-show="toolBarContentVisible">
            <div class="analysis-content-title">
              <div>{{ getToolBarContentTitle }}</div>
              <div style="cursor: pointer;" @click="toolBarContentVisible=false"><i class="el-icon-close"></i></div>
            </div>

            <!-- 坐标定位 -->
            <div style="padding: 10px;" v-show="activeToolSub==='1-1'">
              <el-form ref="locatorForm1" v-model="pipeFeatureSearch.locatorForm1" label-width="60px">
                <el-form-item label="X坐标">
                  <el-input v-model="pipeFeatureSearch.locatorForm1.x" size="mini"/>
                </el-form-item>
                <el-form-item label="Y坐标">
                  <el-input v-model="pipeFeatureSearch.locatorForm1.y" size="mini"/>
                </el-form-item>
                <el-form-item>
                  <el-button size="mini" type="primary" @click="handleAccurateLocatorClick(1)">定位</el-button>
                  <el-button size="mini" type="danger" @click="handleAccurateLocatorClick(2)">重置</el-button>
                </el-form-item>
              </el-form>
            </div>

            <!-- 交叉路口定位 -->
            <div style="padding: 10px;" v-show="activeToolSub==='1-2'">
              <el-form ref="locatorForm2" v-model="pipeFeatureSearch.locatorForm2" label-width="60px">
                <el-form-item label="道路一">
                  <el-autocomplete class="inline-input" v-model="pipeFeatureSearch.locatorForm2.road1" size="mini"
                                   :fetch-suggestions="queryRoadSearch" placeholder="请选择道路一"
                                   @select="handleCrossPointLocatorClick(1, $event)"></el-autocomplete>
                </el-form-item>

                <el-form-item label="道路二">
                  <el-autocomplete class="inline-input" v-model="pipeFeatureSearch.locatorForm2.road2" size="mini"
                                   :fetch-suggestions="queryRoadSearch" placeholder="请选择道路二"
                                   @select="handleCrossPointLocatorClick(2, $event)"></el-autocomplete>
                </el-form-item>

                <el-form-item>
                  <el-button size="mini" type="primary" @click="handleCrossPointLocatorClick(3)">查询</el-button>
                  <el-button size="mini" type="danger" @click="handleCrossPointLocatorClick(4)">重置</el-button>
                </el-form-item>

              </el-form>
            </div>

            <!-- 模糊定位 -->
            <div style="padding: 10px;" v-show="activeToolSub==='1-3'">
              <el-form :inline="true" ref="locatorForm3" v-model="pipeFeatureSearch.locatorForm3" label-width="60px">
                <el-form-item label="关键字">
                  <el-input v-model="pipeFeatureSearch.locatorForm3.keywords" size="mini" placeholder="请输入关键字"
                            style="width: 180px;"/>
                </el-form-item>
                <el-form-item>
                  <el-button size="mini" type="primary" @click="handleVagueLocatorClick(1)">查询</el-button>
                  <el-button size="mini" type="danger" @click="handleVagueLocatorClick(2)">重置</el-button>
                </el-form-item>
              </el-form>

              <el-table :data="pipeFeatureSearch.locatorForm3.tableData" size="mini" border style="width: 100%"
                        highlight-current-row :height="400" @row-click="handleVagueLocatorClick(3, $event)">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column prop="id" label="编号" width="100"></el-table-column>
                <el-table-column prop="name" label="名称" width="220"></el-table-column>
                <el-table-column prop="category" label="类型" width="80" align="center"></el-table-column>
              </el-table>
            </div>

            <!-- 道路缓冲查询 -->
            <div style="padding: 10px;" v-show="activeToolSub==='2-1'">

              <el-form :inline="true" ref="statisticForm1" v-model="pipeFeatureSearch.statisticForm1"
                       label-width="80px">
                <el-form-item label="道路名称">
                  <el-autocomplete class="inline-input" v-model="pipeFeatureSearch.statisticForm1.road" size="mini"
                                   :fetch-suggestions="queryRoadSearch" placeholder="请选择道路"
                                   @select="handleRoadBufferClick(1, $event)"></el-autocomplete>
                </el-form-item>
                <el-form-item label="缓冲距离">
                  <el-input-number v-model="pipeFeatureSearch.statisticForm1.radius" :min="1" size="mini"
                                   placeholder="请输入"
                                   style="width: 100px;">
                  </el-input-number>
                  米
                  <el-select v-model="pipeFeatureSearch.statisticForm1.iType" size="mini" style="width: 80px;"
                             @change="handleRoadBufferClick(2)">
                    <el-option :value="1" label="管点"></el-option>
                    <el-option :value="2" label="管线"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-button size="mini" type="primary" @click="handleRoadBufferClick(3)">查询</el-button>
                  <el-button size="mini" type="danger" @click="handleRoadBufferClick(4)">重置</el-button>
                  <el-button size="mini" type="warning" @click="handleRoadBufferClick(5)">导出</el-button>
                </el-form-item>
              </el-form>

              <el-table v-if="pipeFeatureSearch.statisticForm1.iType===1"
                        :data="pipeFeatureSearch.statisticForm1.tableData"
                        :loading="pipeFeatureSearch.statisticForm1.queryLoading"
                        size="mini" border style="width: 100%" highlight-current-row :height="400"
                        @row-click="handleRoadBufferClick(6, $event)">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column v-for="item in pointTableColumns" :prop="item.prop" :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>

              <el-table v-if="pipeFeatureSearch.statisticForm1.iType===2"
                        :data="pipeFeatureSearch.statisticForm1.tableData"
                        :loading="pipeFeatureSearch.statisticForm1.queryLoading"
                        size="mini" border style="width: 100%" highlight-current-row :height="400"
                        @row-click="handleRoadBufferClick(6, $event)">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column v-for="item in lineTableColumns" :prop="item.prop" :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 管线要素查询 -->
            <div style="padding: 10px;" v-show="activeToolSub==='2-2'">
              <div style="display: flex;justify-content: end;margin-bottom: 10px;">
                <el-select size="mini" placeholder="请选择" style="width: 100px;margin-right: 10px;"
                           v-model="pipeFeatureSearch.type">
                  <el-option label="管点" value="point"></el-option>
                  <el-option label="管线" value="line"></el-option>
                </el-select>

                <span style="margin-right: 5px;color: #606266;">字段名称</span>
                <!-- 管点字段 -->
                <el-select size="mini" style="width: 140px;margin-right: 10px;" v-if="pipeFeatureSearch.type==='point'"
                           v-model="pipeFeatureSearch.pointField">
                  <el-option v-for="option in pipeFeatureSearch.pointFieldData"
                             :value="option.field"
                             :label="option.name">
                  </el-option>
                </el-select>
                <!-- 管线字段 -->
                <el-select size="mini" style="width: 140px;margin-right: 10px;" v-if="pipeFeatureSearch.type==='line'"
                           v-model="pipeFeatureSearch.lineField">
                  <el-option v-for="option in pipeFeatureSearch.lineFieldData"
                             :value="option.field"
                             :label="option.name">
                  </el-option>
                </el-select>

                <!-- 管点操作符 -->
                <el-select size="mini" style="width: 120px;margin-right: 10px;" v-if="pipeFeatureSearch.type==='point'"
                           v-model="pipeFeatureSearch.pointOperator">
                  <el-option v-for="option in pipeFeatureSearch.pointOperatorData[pipeFeatureSearch.pointField]"
                             :value="option.id"
                             :label="option.name">
                  </el-option>
                </el-select>

                <!-- 管线操作符 -->
                <el-select size="mini" style="width: 120px;margin-right: 10px;" v-if="pipeFeatureSearch.type==='line'"
                           v-model="pipeFeatureSearch.lineOperator">
                  <el-option v-for="option in pipeFeatureSearch.lineOperatorData[pipeFeatureSearch.lineField]"
                             :value="option.id"
                             :label="option.name">
                  </el-option>
                </el-select>

                <!-- 字段值 -->
                <el-input size="mini" v-model="pipeFeatureSearch.value" style="width: 120px;margin-right: 10px;"
                          placeholder="请输入字段值"/>

                <div>
                  <el-button size="mini" type="primary" icon="search" @click="handlePipeFeatureQuery(1)">查询
                  </el-button>
                  <el-button size="mini" type="warning" @click="handlePipeFeatureQuery(2)">导出</el-button>
                </div>
              </div>

              <!-- 管点表数据 -->
              <el-table size="mini" border style="width: 100%" v-if="pipeFeatureSearch.type==='point'"
                        :height="400" :data="pipeFeatureSearch.pointData"
                        @row-click="handlePipeFeatureQuery(3, $event)">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column v-for="item in pointTableColumns" :prop="item.prop" :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>

              <!-- 管线表数据 -->
              <el-table size="mini" border style="width: 100%" v-if="pipeFeatureSearch.type==='line'"
                        :height="400" :data="pipeFeatureSearch.lineData" @row-click="handlePipeFeatureQuery(3, $event)">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column v-for="item in lineTableColumns" :prop="item.prop" :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>

            </div>

            <!-- 管线长度查询 -->
            <div style="padding: 10px;" v-show="activeToolSub==='2-3'">
              <div style="display: flex;justify-content: end;margin-bottom: 10px;">
                <div>
                  <span style="margin-right: 5px;color: #606266;">管线材质</span>
                  <el-select size="mini" style="width: 180px;margin-right: 10px;" multiple
                             v-model="pipeFeatureSearch.pipeLengthQueryForm.pipeMaterial">
                    <el-option v-for="dict in dictTypes['material_type']"
                               :key="dict.value"
                               :label="dict.label"
                               :value="dict.value">
                    </el-option>
                  </el-select>
                </div>

                <div>
                  <span style="margin-right: 5px;color: #606266;">管线口径</span>
                  <el-select size="mini" style="width: 180px;margin-right: 10px;" multiple
                             v-model="pipeFeatureSearch.pipeLengthQueryForm.pipeDn">
                    <el-option v-for="dict in dictTypes['caliber_type']"
                               :key="dict.value"
                               :label="dict.label"
                               :value="dict.value">
                    </el-option>
                  </el-select>
                </div>

                <div>
                  <el-button size="mini" type="primary" icon="search" @click="handlePipeLengthQuery(1)">查询</el-button>
                  <el-button size="mini" type="warning" @click="handlePipeLengthQuery(2)">导出</el-button>
                </div>
              </div>

              <div style="width: 100%;margin: 10px 0;text-align: right;color: #1890ff;">
                管线长度合计：{{ getAllPipeLength }}
              </div>

              <el-table size="mini" border style="width: 100%" v-loading="pipeFeatureSearch.pipeLengthQueryLoading"
                        :data="pipeFeatureSearch.pipeLengthTableData" :height="400" :span-method="pipeLengthSpanMethod">
                <el-table-column v-for="item in pipeFeatureSearch.pipeLengthTableColumns" :prop="item.prop"
                                 :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 区域内管线长度查询 -->
            <div style="padding: 10px;" v-show="activeToolSub==='2-4'">
              <div style="display: flex;justify-content: end;margin-bottom: 10px;">
                <div>
                  <el-button size="mini" type="primary" icon="search" @click="handlePipeLengthInPolygonQuery(1)">
                    区域选择
                  </el-button>
                  <el-button size="mini" type="primary" icon="search" @click="handlePipeLengthInPolygonQuery(2)">查询
                  </el-button>
                  <el-button size="mini" type="warning" @click="handlePipeLengthInPolygonQuery(3)">导出</el-button>
                </div>
              </div>

              <div style="width: 100%;margin: 10px 0;text-align: right;color: #1890ff;">
                管线长度合计：{{ getAllPipeLengthInPolygon }}
              </div>

              <el-table size="mini" border style="width: 100%"
                        v-loading="pipeFeatureSearch.pipeLengthInPolygonQueryLoading"
                        :data="pipeFeatureSearch.pipeLengthInPolygonTableData" :height="400"
                        :span-method="pipeLengthInPolygonSpanMethod">
                <el-table-column v-for="item in pipeFeatureSearch.pipeLengthInPolygonTableColumns" :prop="item.prop"
                                 :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 设施数量查询 -->
            <div style="padding: 10px;" v-show="activeToolSub==='2-5'">
              <div style="display: flex;justify-content: end;margin-bottom: 10px;">
                <div>
                  <span style="margin-right: 5px;color: #606266;">设施类型</span>
                  <el-select size="mini" style="width: 180px;margin-right: 10px;" multiple
                             v-model="pipeFeatureSearch.pointTypeCountQueryForm.pointType">
                    <el-option v-for="dict in dictTypes['scode_type']"
                               :key="dict.value"
                               :label="dict.label"
                               :value="dict.value">
                    </el-option>
                  </el-select>
                </div>

                <div>
                  <el-button size="mini" type="primary" icon="search" @click="handlePointTypeCountQuery(1)">查询
                  </el-button>
                  <el-button size="mini" type="warning" @click="handlePointTypeCountQuery(2)">导出</el-button>
                </div>
              </div>

              <div style="width: 100%;margin: 10px 0;text-align: right;color: #1890ff;">
                设施数量合计：{{ getPointTypeCount }}个
              </div>

              <el-table size="mini" border style="width: 100%" v-loading="pipeFeatureSearch.pointTypeQueryLoading"
                        :data="pipeFeatureSearch.pointTypeCountTableData" :height="400">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column v-for="item in pipeFeatureSearch.pointTypeCountTableColumns" :prop="item.prop"
                                 :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 区域内设施数量查询 -->
            <div style="padding: 10px;" v-show="activeToolSub==='2-6'">
              <div style="display: flex;justify-content: end;margin-bottom: 10px;">
                <div>
                  <el-button size="mini" type="primary" icon="search" @click="handlePointTypeCountInPolygonQuery(1)">
                    区域选择
                  </el-button>
                  <el-button size="mini" type="primary" icon="search" @click="handlePointTypeCountInPolygonQuery(2)">查询
                  </el-button>
                  <el-button size="mini" type="warning" @click="handlePointTypeCountInPolygonQuery(3)">导出</el-button>
                </div>
              </div>

              <div style="width: 100%;margin: 10px 0;text-align: right;color: #1890ff;">
                设施数量合计：{{ getPointTypeCountInPolygon }}个
              </div>

              <el-table size="mini" border style="width: 100%"
                        v-loading="pipeFeatureSearch.pointTypeInPolygonQueryLoading"
                        :data="pipeFeatureSearch.pointTypeCountInPolygonTableData" :height="400">
                <el-table-column type="index" label="#" width="50" align="center"/>
                <el-table-column v-for="item in pipeFeatureSearch.pointTypeCountTableColumns" :prop="item.prop"
                                 :label="item.label"
                                 :width="item.width" :align="item.align">
                  <template slot-scope="scope">
                    <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                    <span v-else> {{ scope.row[item.prop] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 关阀预案分析 -->
            <div style="padding: 10px;" v-show="activeToolSub==='3-1'">
              <div style="text-align: right;">
                <el-button size="mini" type="primary" icon="el-icon-location-outline"
                           v-on:click.stop="handleLeakAnalysisClick(1)">爆管选点
                </el-button>
                <el-button size="mini" type="success" icon="el-icon-search"
                           v-on:click.stop="handleLeakAnalysisClick(2)">爆管分析
                </el-button>
                <el-button size="mini" type="warning" icon="el-icon-download"
                           v-on:click.stop="handleLeakAnalysisClick(3)">导出
                </el-button>
              </div>

              <div style="display: flex;justify-content: space-between;margin-top: 10px;">
                <div style="margin-left: 10px;">
                  <el-table :data="pipeFeatureSearch.leakAnalysisForm.tableData" size="mini" border style="width: 100%"
                            highlight-current-row :height="400" @row-click="handleLeakAnalysisClick(4, $event)">
                    <el-table-column type="index" label="#" width="50" align="center"/>
                    <el-table-column v-for="item in pointTableColumns" :prop="item.prop" :label="item.label"
                                     :width="item.width" :align="item.align">
                      <template slot-scope="scope">
                        <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                        <span v-else> {{ scope.row[item.prop] }}</span>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </div>

            <!-- 火灾分析 -->
            <div style="padding: 10px;" v-show="activeToolSub==='3-2'">
              <div style="text-align: right;">
                <el-button size="mini" type="primary" icon="el-icon-location-outline"
                           style="margin-right: 10px;" @click="handleFeatureFireHydrantQueryClick(1)">火灾选点
                </el-button>
                查找范围
                <el-input-number style="width: 120px;" size="mini" :min="1"
                                 v-model="pipeFeatureSearch.fireHydrantForm.bufferRange"></el-input-number>
                米
                <el-button size="mini" type="success" icon="el-icon-search"
                           style="margin-left: 10px;" @click="handleFeatureFireHydrantQueryClick(2)">查询消防栓
                </el-button>
                <el-button size="mini" type="warning" icon="el-icon-download"
                           @click="handleFeatureFireHydrantQueryClick(3)">导出
                </el-button>
              </div>

              <div style="margin-top: 10px;">
                <el-table size="mini" border style="width: 100%" :height="400"
                          :loading="pipeFeatureSearch.fireHydrantForm.fireHydrantLoading"
                          :data="pipeFeatureSearch.fireHydrantForm.fireHydrantTableData"
                          @row-click="handleFeatureFireHydrantQueryClick(4, $event)">
                  <el-table-column type="index" label="#" width="50" align="center"/>
                  <el-table-column v-for="item in pipeFeatureSearch.fireHydrantForm.fireHydrantTableColumns"
                                   :prop="item.prop"
                                   :label="item.label"
                                   :width="item.width" :align="item.align">
                    <template slot-scope="scope">
                      <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                      <span v-else> {{ scope.row[item.prop] }}</span>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>

            <!-- 预警分析 -->
            <div style="padding: 10px;" v-show="activeToolSub==='3-3'">
              <div style="text-align: right;">
                <el-form :inline="true" v-model="pipeFeatureSearch.featureAlarmQueryForm">
                  <el-form-item label="预警对象">
                    <el-select size="mini" placeholder="请选择" style="width: 160px;"
                               v-model="pipeFeatureSearch.featureAlarmQueryForm.featureType"
                    >
                      <el-option label="管线" value="line"></el-option>
                      <el-option label="管点" value="point"></el-option>
                      <el-option v-for="dict in dictTypes['scode_type']"
                                 :key="dict.value"
                                 :label="dict.label"
                                 :value="dict.value"/>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="年限">
                    <el-select size="mini" placeholder="请选择" style="width: 160px;"
                               v-model="pipeFeatureSearch.featureAlarmQueryForm.alarmType"
                    >
                      <el-option label="预警年限" value="warning"></el-option>
                      <el-option label="超期年限" value="overdue"></el-option>
                    </el-select>
                    <el-input-number size="mini" placeholder="请输入预警年限" :min="1" style="width: 120px;"
                                     v-model="pipeFeatureSearch.featureAlarmQueryForm.featureYears"></el-input-number>
                  </el-form-item>
                  <el-form-item>
                    <el-button size="mini" type="success" icon="el-icon-search"
                               @click="handleFeatureAlarmQueryClick(1)">
                      查询
                    </el-button>
                    <el-button size="mini" type="warning" icon="el-icon-download"
                               @click="handleFeatureAlarmQueryClick(2)">导出
                    </el-button>
                  </el-form-item>
                </el-form>
              </div>

              <div style="margin-top: 10px;">
                <el-table size="mini" border style="width: 100%"
                          v-if="pipeFeatureSearch.featureAlarmQueryForm.featureType!=='line'"
                          :data="pipeFeatureSearch.featureAlarmPointTableData"
                          v-loading="pipeFeatureSearch.featureAlarmQueryLoading" :height="400"
                          @row-click="handleFeatureAlarmQueryClick(3, $event)">
                  <el-table-column type="index" label="#" width="50" align="center"/>
                  <el-table-column v-for="item in pointTableColumns" :prop="item.prop" :label="item.label"
                                   :width="item.width" :align="item.align">
                    <template slot-scope="scope">
                      <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                      <span v-else> {{ scope.row[item.prop] }}</span>
                    </template>
                  </el-table-column>
                </el-table>

                <el-table size="mini" border style="width: 100%"
                          v-if="pipeFeatureSearch.featureAlarmQueryForm.featureType==='line'"
                          :data="pipeFeatureSearch.featureAlarmLineTableData"
                          v-loading="pipeFeatureSearch.featureAlarmQueryLoading" :height="400"
                          @row-click="handleFeatureAlarmQueryClick(3, $event)">
                  <el-table-column type="index" label="#" width="50" align="center"/>
                  <el-table-column v-for="item in lineTableColumns" :prop="item.prop" :label="item.label"
                                   :width="item.width" :align="item.align">
                    <template slot-scope="scope">
                      <span v-if="item.slotFunc != null"> {{ item.slotFunc(scope.row) }}</span>
                      <span v-else> {{ scope.row[item.prop] }}</span>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>

            <!-- 连通性分析 -->
            <div style="padding: 10px;" v-show="activeToolSub==='3-4'">
              <div style="text-align: right;">
                <div style="margin-bottom: 10px;">
                  <el-button size="mini" type="primary" icon="el-icon-search" @click="handleLinkAnalysis(1)">起点选样
                  </el-button>
                  <el-button size="mini" type="primary" icon="el-icon-search" @click="handleLinkAnalysis(2)">终点选样
                  </el-button>
                  <el-button size="mini" type="success" icon="el-icon-search" @click="handleLinkAnalysis(3)">查询
                  </el-button>
                </div>

                <el-form :inline="true" label-width="80px">
                  <el-form-item label="起始管点">
                    <el-input v-model="pipeFeatureSearch.linkAnalysisResult.start.EXP_NO" size="mini" readonly
                              style="width: 100px;"/>
                  </el-form-item>
                  <el-form-item label="终止管点">
                    <el-input v-model="pipeFeatureSearch.linkAnalysisResult.end.EXP_NO" size="mini" readonly
                              style="width: 100px;"/>
                  </el-form-item>
                </el-form>
              </div>

              <div v-if="pipeFeatureSearch.linkAnalysisResult.visible">
                <div style="color: #1890ff;font-size: 21px;font-weight: bold;">连通性分析结果</div>
                <div class="link-analysis-box">
                  <div class="link-analysis-box-item">{{ pipeFeatureSearch.linkAnalysisResult.result }}</div>
                </div>
              </div>
            </div>

            <!-- 高程差分析 -->
            <div style="padding: 10px;" v-show="activeToolSub==='3-5'">
              <div style="text-align: right;">
                <div style="margin-bottom: 10px;">
                  <el-button size="mini" type="primary" icon="el-icon-search" @click="handleAltitudeAnalysis(1)">
                    起点选样
                  </el-button>
                  <el-button size="mini" type="primary" icon="el-icon-search" @click="handleAltitudeAnalysis(2)">
                    终点选样
                  </el-button>
                  <el-button size="mini" type="success" icon="el-icon-search" @click="handleAltitudeAnalysis(3)">
                    查询
                  </el-button>
                </div>

                <el-form :inline="true" label-width="80px">
                  <el-form-item label="起始管点">
                    <el-input v-model="pipeFeatureSearch.altitudeResult.start.EXP_NO" size="mini" readonly
                              style="width: 100px;"/>
                  </el-form-item>
                  <el-form-item label="终止管点">
                    <el-input v-model="pipeFeatureSearch.altitudeResult.end.EXP_NO" size="mini" readonly
                              style="width: 100px;"/>
                  </el-form-item>
                </el-form>
              </div>

              <div>
                <el-descriptions class="margin-top" :column="2" size="mini" direction="vertical" border>
                  <el-descriptions-item>
                    <template slot="label">
                      <i class="el-icon-user"></i>
                      起点名称
                    </template>
                    {{ pipeFeatureSearch.altitudeResult.start.FEATURE }}
                  </el-descriptions-item>
                  <el-descriptions-item>
                    <template slot="label">
                      <i class="el-icon-user"></i>
                      终点名称
                    </template>
                    {{ pipeFeatureSearch.altitudeResult.end.FEATURE }}
                  </el-descriptions-item>
                  <el-descriptions-item>
                    <template slot="label">
                      <i class="el-icon-user"></i>
                      起点位置
                    </template>
                    {{ pipeFeatureSearch.altitudeResult.start.ADDRESS }}
                  </el-descriptions-item>
                  <el-descriptions-item>
                    <template slot="label">
                      <i class="el-icon-user"></i>
                      终点位置
                    </template>
                    {{ pipeFeatureSearch.altitudeResult.end.ADDRESS }}
                  </el-descriptions-item>
                  <el-descriptions-item>
                    <template slot="label">
                      <i class="el-icon-user"></i>
                      起点高程
                    </template>
                    {{ pipeFeatureSearch.altitudeResult.start.H }}
                  </el-descriptions-item>
                  <el-descriptions-item>
                    <template slot="label">
                      <i class="el-icon-user"></i>
                      终点高程
                    </template>
                    {{ pipeFeatureSearch.altitudeResult.end.H }}
                  </el-descriptions-item>
                </el-descriptions>

                <div v-show="pipeFeatureSearch.altitudeResult.visible">
                  <div style="color: #1890ff;font-size: 16px;font-weight: bold;margin: 10px 0;">
                    起点和终点高程差：{{ pipeFeatureSearch.altitudeResult.result }}米
                  </div>
                  <div>
                    <canvas id="altitudeCanvas" width="600" height="200" ref="altitudeCanvas"></canvas>
                  </div>
                </div>
              </div>
            </div>

            <!-- 文件管理 -->
            <div style="padding: 10px;width: 760px;" v-show="activeToolSub==='4-1'">
              <div style="display: flex;justify-content: space-between;margin-bottom: 10px;">
                <div>
                  <el-button size="mini" type="primary" @click="handleFeatureFileManage(1)">
                    要素选择
                  </el-button>
                </div>
                <div>
                  <el-button size="mini" type="primary" @click="handleFeatureFileManage(2)">
                    文件上传
                  </el-button>
                </div>
              </div>

              <div style="display: flex;justify-content: space-between;">
                <div style="width: 21%;height: 400px;">
                  <el-scrollbar style="width: 100%;height: 100%;">
                    <el-tree :data="featureTreeData"
                             ref="refFeatureTree"
                             node-key="id"
                             highlight-current
                             default-expand-all
                             @node-click="handleFeatureFileManage(3, $event)">
                      <template slot-scope="{ node, data }">
                        <span style="font-size: 12px;">{{ data.label }}</span>
                      </template>
                    </el-tree>
                  </el-scrollbar>
                </div>

                <div style="width: calc(79% - 10px);margin-left: 10px;">
                  <el-table size="mini" border style="width: 100%" :height="400" :data="featureFileData"
                            v-loading="featureFileDataLoading">
                    <el-table-column type="index" label="#" width="50" align="center"/>
                    <!--                <el-table-column label="文件名" align="center" prop="fileName" />-->
                    <el-table-column label="文件名" align="center" prop="original_name"/>
                    <!--                  <el-table-column label="文件后缀" align="center" prop="fileSuffix"/>-->
                    <!--                <el-table-column label="文件展示" align="center" prop="url">-->
                    <!--                  <template slot-scope="scope">-->
                    <!--                    <ImagePreview-->
                    <!--                      v-if="previewListResource && checkFileSuffix(scope.row.fileSuffix)"-->
                    <!--                      :width=100 :height=100-->
                    <!--                      :src="scope.row.url"-->
                    <!--                      :preview-src-list="[scope.row.url]"/>-->
                    <!--                    <span v-text="scope.row.url"-->
                    <!--                          v-if="!checkFileSuffix(scope.row.fileSuffix) || !previewListResource"/>-->
                    <!--                  </template>-->
                    <!--                </el-table-column>-->
                    <el-table-column label="上传人" align="center" prop="create_by" width="90"/>
                    <el-table-column label="上传时间" align="center" prop="create_time" width="100">
                      <template slot-scope="scope">
                        <span>{{ parseTime(scope.row.create_time, '{y}-{m}-{d}') }}</span>
                      </template>
                    </el-table-column>
                    <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
                      <template slot-scope="scope">
                        <el-button
                          size="mini"
                          type="text"
                          @click="handleFeatureFileManage(4, scope.row)"
                        >下载
                        </el-button>
                        <el-button
                          size="mini"
                          type="text"
                          @click="handleFeatureFileManage(5, scope.row)"
                        >删除
                        </el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </div>

            <!-- 导入对话框 -->
            <el-dialog :title="featureFileUpload.title" :visible.sync="featureFileUpload.open" width="400px"
                       append-to-body>
              <el-upload ref="refFileUpload"
                         multiple
                         :limit="10"
                         accept="*"
                         :headers="featureFileUpload.headers"
                         :action="featureFileUpload.url+ '?tbl=' + featureFileUpload.tbl + '&id=' + featureFileUpload.id + '&type=' + featureFileUpload.type"
                         :disabled="featureFileUpload.isUploading"
                         :on-progress="handleFileUploadProgress"
                         :on-success="handleFileSuccess"
                         :auto-upload="false"
                         drag>
                <i class="el-icon-upload"></i>
                <div class="el-upload__text">每次最多可上传10个文件，将文件拖到此处，或<em>点击选择</em></div>
              </el-upload>
              <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="submitFileForm">上传文件</el-button>
                <el-button type="danger" @click="featureFileUpload.open = false">关 闭</el-button>
              </div>
            </el-dialog>
          </div>
        </L7Map>
      </div>

      <MouseTip ref="refMouseTip">{{ mouseTipText }}</MouseTip>
    </ContentWrap>
  </div>
</template>

<script>
import * as turf from "@turf/turf";
import L7Map from "@/components/L7Maps/map.vue";
import {Marker, MarkerLayer, LineLayer} from "@antv/l7";
import {DrawPoint, DrawPolygon, DrawRect, DrawEvent} from '@antv/l7-draw';
import MouseTip from '@/components/MouseTip/index.vue'
import {
  loadFeaturesByWFS,
  initPolylineLayer,
  initPointLayer,
  initSceneImage,
  initSceneLegendControl,
  initSceneZoomControl,
  initMapLayerTree,
  callSQLViewByWFS,
  initLineLabelLayer
} from '@/utils/wfsUtil'
import {getOssRecords, removeOss} from '@/api/leakage/pgedit'
import ExportExcel from '@/utils/excel/excel'
import {Loading, Message} from 'element-ui'
import {getToken} from "@/utils/auth";
import {blobValidate} from "@/utils/ruoyi";
import {saveAs} from 'file-saver'
import axios from 'axios'
import {findTableData} from "@/api/leakage/pgedit";

// 数组求和
function sumArray(arr) {
  return arr.reduce(function (total, value) {
    return total + value;
  }, 0);
}

// 字符类字段比较运算符
const strOperators = [
  {id: 'EQ', name: '等于'},
  {id: 'LIKE', name: '类似'}
]

// 数字类字段比较运算符
const numOperators = [
  {id: 'EQ', name: '等于'},
  {id: 'GT', name: '大于',},
  {id: 'GE', name: '大于等于',},
  {id: 'LT', name: '小于',},
  {id: 'LE', name: '小于等于',},
]

// 表格行合并辅助工具类
function getSpanArr(data, key, resultArr) {
  let pos = 0
  // 遍历数据
  for (let i = 0; i < data.length; i++) {
    // 如果是第一个数据，就将列表spanArr添加一个1，表示暂时只有一个名字相同的、且将索引pos赋值为0
    if (i === 0) {
      resultArr.push(1);
      pos = 0
    } else {
      // 判断当前元素与上一个元素是否相同
      if (data[i][key] === data[i - 1][key]) {
        // 如果相同就将索引为 pos 的值加一
        resultArr[pos] += 1;
        // 且将数组添加 0
        resultArr.push(0);
      } else {
        // 如果元素不同了，就可以通过索引为 pos 的值知晓应该需要合并的行数
        // 同时，我们再次添加一个值1，表示重新开始判断重复姓名的次数
        resultArr.push(1);
        // 同时 索引加一
        pos = i;
      }
    }
  }
}

export default {
  name: 'PipeNetworkAnalysis',
  components: {L7Map, MouseTip},
  data() {
    return {
      dictTypes: {
        'caliber_type': [],
        'material_type': [],
        'scode_type': []
      },
      // 屏幕高度
      screenHeight: null,
      // 地图场景对象
      mapScene: undefined,
      // 图例控件
      legendControl: undefined,
      // 图层面板是否可见
      layerPanelVisible: true,
      // 图例面板是否可见
      legendPanelVisible: true,
      // 分析工具面板是否可见
      analysisToolPanelVisible: true,
      // 当前激活分析工具 - 一级
      activeToolMain: '1',
      // 当前激活分析工具 - 二级
      activeToolSub: '',
      // 分析享工具选项
      analysisToolOptions: [
        {
          key: '1', name: '地图定位', tools: [
            {key: '1-1', name: '坐标定位'},
            // {key: '1-2', name: '交叉路口定位'},
            {key: '1-3', name: '模糊定位'},
          ]
        },
        {
          key: '2', name: '查询统计', tools: [
            {key: '2-1', name: '道路缓冲查询'},
            {key: '2-2', name: '管线要素查询'},
            {key: '2-3', name: '管线长度查询'},
            {key: '2-4', name: '区域内管线长度查询'},
            {key: '2-5', name: '设施数量查询'},
            {key: '2-6', name: '区域内设施数量查询'},
          ]
        },
        {
          key: '3', name: '空间分析', tools: [
            {key: '3-1', name: '关阀预案分析'},
            {key: '3-2', name: '火灾分析'},
            {key: '3-3', name: '预警分析'},
            {key: '3-4', name: '连通性分析'},
            {key: '3-5', name: '高程差分析'},
          ]
        },
        {
          key: '4', name: '文件管理', tools: [
            {key: '4-1', name: '文件管理'},
          ]
        },
      ],
      // 鼠标跟随文字
      mouseTipText: '测试一下',
      // 空间分析线标记图层
      analysisLineLayer: undefined,
      // 图层树数据
      layerTreeData: [],
      layerTreeLoading: true,
      // 图层树默认选中节点数据
      defaultCheckTreeData: [],
      // 图层树选中的树节点键值
      selectedTreeNodeKeys: [],
      // 工具栏是否可见
      toolBtnBarVisible: false,
      // 工具栏激活工具索引
      toolBtnIndex: false,
      // 工具按钮对应操作内容是否可见
      toolBarContentVisible: false,
      // 管线标记点类型
      linePointMarkType: undefined,
      // 空间分析查询参数
      pipeFeatureSearch: {
        // 管线道路数据
        polylineRoads: [],
        // 坐标定位表单
        locatorForm1: {},
        // 交叉路口定位表单
        locatorForm2: {},
        // 模糊定位表单
        locatorForm3: {
          tableData: []
        },
        // 道路缓冲查询表单
        statisticForm1: {
          radius: 50,
          iType: 1,
          tableData: [],
          queryLoading: false,
        },
        // ========管线要素查询变量========
        value: '',
        type: 'point',
        pointField: 'SCODE',
        pointFieldData: [
          {field: 'SCODE', name: '设施类别'},
          {field: 'METERIAL', name: '材质',},
          {field: 'SPEC', name: '规格',},
          {field: 'DEEP', name: '埋深',},
        ],
        pointOperator: 'EQ',
        pointOperatorData: {
          'SCODE': strOperators,
          'METERIAL': strOperators,
          'SPEC': numOperators,
          'DEEP': numOperators,
        },
        lineField: 'D_S',
        lineFieldData: [
          {field: 'D_S', name: '管径',},
          {field: 'MATERIAL', name: '材质',},
          {field: 'LLENGTH', name: '管线长度',},
          {field: 'S_DEEP', name: '起点埋深',},
          {field: 'E_DEEP', name: '终点埋深',},
        ],
        lineOperator: 'EQ',
        lineOperatorData: {
          'D_S': numOperators,
          'MATERIAL': strOperators,
          'LLENGTH': numOperators,
          'S_DEEP': numOperators,
          'E_DEEP': numOperators,
        },
        pointData: [],
        lineData: [],
        // ========管线要素查询变量========END
        // ========管线长度查询变量========
        // 管线长度查询表单
        pipeLengthQueryForm: {},
        // 管线长度查询表格列
        pipeLengthTableColumns: [
          {label: '管线材质', prop: 'material', width: '', align: 'center', slotFunc: null},
          {label: '管线口径', prop: 'caliber', width: '', align: 'center', slotFunc: null},
          {
            label: '管线长度(米)', prop: 'total_length', width: '', align: 'center', slotFunc: (row) => {
              return row.total_length.toFixed(2)
            }
          },
        ],
        pipeLengthTableData: [],
        // 管线长度表格行合并索引数组
        pipeLengthSpanArray: [],
        // 管线长度查询数据状态
        pipeLengthQueryLoading: false,
        // ========管线长度查询变量========END
        // ========区域内管线长度查询变量========
        pipeLengthInPolygonPoints: '',
        // 管线长度查询表格列
        pipeLengthInPolygonTableColumns: [
          {label: '管线材质', prop: 'material', width: '130', align: 'center', slotFunc: null},
          {label: '管线口径', prop: 'diameter', width: '130', align: 'center', slotFunc: null},
          {
            label: '管线长度(米)', prop: 'total_length', width: '130', align: 'center', slotFunc: (row) => {
              return row.total_length.toFixed(2)
            }
          },
        ],
        // 区域内管线长度查询数据
        pipeLengthInPolygonTableData: [],
        // 区域内管线长度表格行合并索引数组
        pipeLengthInPolygonSpanArray: [],
        // 区域内管线长度查询数据状态
        pipeLengthInPolygonQueryLoading: false,
        // ========区域内管线长度查询变量========END
        // ========设施数量查询变量========
        // 设施数量查询表单
        pointTypeCountQueryForm: {},
        // 设施数量表格列
        pointTypeCountTableColumns: [
          {label: '设施类型', prop: 'facility_type', width: '200', align: 'center', slotFunc: null},
          {label: '个数', prop: 'facility_count', width: '180', align: 'center', slotFunc: null},
        ],
        // 设施数量查询数据
        pointTypeCountTableData: [],
        // 设施数量查询数据状态
        pointTypeQueryLoading: false,
        // ========设施数量查询变量========END
        // ========区域内设施数量查询变量========
        pointTypeInPolygonPoints: '',
        pointTypeInPolygonQueryLoading: false,
        pointTypeCountInPolygonTableData: [],
        // ========区域内设施数量查询变量========END
        // ========关阀预案查询变量========
        leakAnalysisForm: {
          leakPoint: null,
          queryLoading: false,
          tableData: []
        },
        // ========关阀预案查询变量========END
        // ========火灾分析查询变量========
        fireHydrantForm: {
          // 火灾点
          coordinate: '',
          // 查找范围
          bufferRange: 100,
          // 数据查询状态
          fireHydrantLoading: false,
          // 消防栓表格列
          fireHydrantTableColumns: [
            {label: '点号', prop: 'exp_no', width: '100', align: 'center', slotFunc: null},
            {label: '设施类别', prop: 'facility_type', width: '100', align: 'center', slotFunc: null},
            {label: '设施名称', prop: 'feature', width: '100', align: 'center', slotFunc: null},
            {label: '地址', prop: 'address', width: '180', align: 'center', slotFunc: null},
            {label: '材质', prop: 'meterial', width: '100', align: 'center', slotFunc: null},
            {label: '规格', prop: 'spec', width: '100', align: 'center', slotFunc: null},
            {label: '埋深(米)', prop: 'deep', width: '100', align: 'center', slotFunc: null},
            {
              label: '建设日期', prop: 'mdate', width: '100', align: 'center', slotFunc: (row) => {
                return row.mdate ? row.mdate.substr(0, 10) : ''
              }
            },
            {
              label: '距离(米)', prop: 'distance_m', width: '100', align: 'center', slotFunc: (row) => {
                return row.distance_m.toFixed(2)
              }
            },
          ],
          // 消防栓数据
          fireHydrantTableData: [],
        },
        // ========火灾分析查询变量========END
        // ========预警分析查询变量========END
        // 预警分析表单
        featureAlarmQueryForm: {
          featureType: 'line',
          alarmType: 'warning',
          featureYears: 5
        },
        // 预警分析数据
        featureAlarmPointTableData: [],
        featureAlarmLineTableData: [],
        // 预警分析查询数据状态
        featureAlarmQueryLoading: false,
        // ========预警分析查询变量========END
        // 连通性分析结果
        linkAnalysisResult: {
          start: {},
          end: {},
          visible: false,
          result: ''
        },
        // 高程差分析结果
        altitudeResult: {
          start: {},
          end: {},
          visible: false,
          result: ''
        }
      },
      // WFS 要素 数据
      geomLayerData: {
        tenant: '',
        serviceUrl: '',
        pointParams: {},
        pointTableName: '',
        lineParams: {},
        lineTableName: '',
        getTableDataCount: 'qtgis:func_get_table_data_count',
        getPolylineRoads: 'qtgis:func_get_roads',
        getCrossPoints: 'qtgis:func_get_cross_points',
        getBufferFeature: 'qtgis:func_get_buffer_feature',
        getPipeFeature: 'qtgis:func_get_pipe_feature',
        getPipeLength: 'qtgis:func_get_pipe_length',
        getPipeLengthInPolygon: 'qtgis:func_get_pipe_length_in_polygon',
        getDictData: 'qtgis:func_get_dict_data',
        getFacilityCountByType: 'qtgis:func_get_facility_count_by_type',
        getFacilityCountByTypeInPolygon: 'qtgis:func_get_facility_count_by_type_in_polygon',
        getFacilitiesByWarningYears: 'qtgis:func_get_facilities_by_warning_years',
        getLeakClosestValve: 'qtgis:func_get_closest_points',
        getFireHydrant: 'qtgis:func_get_fire_hydrant',
        getAnalysisConnect: 'qtgis:func_get_analysis_connect',
      },
      // 地图选点工具
      drawLeakPointTool: undefined, // 爆管选点工具
      drawFirePointTool: undefined, // 火灾选点工具
      // 地图上选点值
      mapDrawPoints: {},
      // 管线图层
      polylineLayer: undefined,
      // 管线文本标记图层
      polylineLabelLayer: undefined,
      // 地图平面选点工具
      drawPolygonTool: undefined,
      // 地图上平面选点值
      mapDrawPolygons: {},
      // 地图矩形选点工具
      drawRectTool: undefined,
      // 地图上矩形选点值
      mapDrawRects: {},
      // 管点表格列数据
      pointTableColumns: [
        {label: '点号', prop: 'EXP_NO', width: '100', align: 'left', slotFunc: null},
        {label: '设施类别', prop: 'SCODE', width: '100', align: 'left', slotFunc: null},
        {label: '设施名称', prop: 'FEATURE', width: '100', align: 'left', slotFunc: null},
        {label: '位置', prop: 'ADDRESS', width: '200', align: 'left', slotFunc: null},
        {label: '材质', prop: 'METERIAL', width: '80', align: 'center', slotFunc: null},
        {label: '规格', prop: 'SPEC', width: '80', align: 'center', slotFunc: null},
        {label: '埋深(米)', prop: 'DEEP', width: '80', align: 'center', slotFunc: null},
        {
          label: '建设日期', prop: 'MDATE', width: '100', align: 'center', slotFunc: (row) => {
            return row.MDATE ? row.MDATE.substr(0, 10) : ''
          }
        },
      ],
      // 管线表格列数据
      lineTableColumns: [
        {label: '起点编号', prop: 'S_POINT', width: '100', align: 'center', slotFunc: null},
        {label: '终点编号', prop: 'E_POINT', width: '100', align: 'center', slotFunc: null},
        {label: '管线材质', prop: 'D_S', width: '80', align: 'center', slotFunc: null},
        {label: '管线口径', prop: 'MATERIAL', width: '100', align: 'center', slotFunc: null},
        {label: '地址', prop: 'ADDRESS', width: '180', align: 'center', slotFunc: null},
        {label: '起点埋深(米)', prop: 'S_DEEP', width: '100', align: 'center', slotFunc: null},
        {label: '终点埋深(米)', prop: 'E_DEEP', width: '100', align: 'center', slotFunc: null},
        {label: '工程号', prop: 'P_ID', width: '100', align: 'center', slotFunc: null},
        {
          label: '建设日期', prop: 'MDATE', width: '100', align: 'center', slotFunc: (row) => {
            return row.MDATE ? row.MDATE.substr(0, 10) : ''
          }
        },
      ],
      // 文件管理要素树节点数据
      featureTreeData: [],
      // 要素文件附件数据
      featureFileData: [],
      // 是否正在加载要素文件附件数据
      featureFileDataLoading: false,
      // 导入参数
      featureFileUpload: {
        treeNode: null,
        tbl: null,
        id: null,
        type: null,
        open: false,
        title: "文件上传",
        // 是否禁用上传
        isUploading: false,
        // 设置上传的请求头部
        headers: {Authorization: "Bearer " + getToken()},
        // 上传的地址
        url: process.env.VUE_APP_BASE_API + "/qtgis/pgedit/uploadOss"
      },
    }
  },
  methods: {
    // 地图初始化完成后处理
    handleMapLoaded(scene) {
      this.mapScene = scene

      // 添加地图放大缩小控件
      initSceneZoomControl(scene)

      // 添加地图图例控件
      this.legendControl = initSceneLegendControl(scene)

      // 添加地图场景要素图片
      initSceneImage(scene)

      // 初始化火灾分析、关阀预案分析选点工具
      this.initDrawPointTool('fire')
      this.initDrawPointTool('leak')

      // 初始化图层数据
      this.getGisLayers(scene)
    },
    getGisLayers(scene) {
      this.polylineLayer = undefined
      this.polylineLabelLayer = undefined
      this.pointLayerList = []
      this.layerTreeData = []

      let lineLoaded = false, pointLoaded = false

      const queryParams = {
        tableName: 'sys_gis_layer',
        pageNum: 1,
        pageSize: 999999
      }
      // 查询图层表数据
      findTableData(queryParams).then(res => {
        if (res.code === 200 && res.data && res.data.length) {
          this.geomLayerData.pointParams = res.data.filter(item => item.layer_type === 1)[0]
          this.geomLayerData.lineParams = res.data.filter(item => item.layer_type === 2)[0]
          this.geomLayerData.lineTableName = this.geomLayerData.lineParams.target_table
          this.geomLayerData.pointTableName = this.geomLayerData.pointParams.target_table
          this.geomLayerData.tenant = this.geomLayerData.pointParams.tenant_id
          this.geomLayerData.serviceUrl = this.geomLayerData.pointParams.service_url

          // 初始化字典数据
          this.initDictTypeOptions()

          // 加载道路数据
          setTimeout(() => {
            const {getPolylineRoads} = this.geomLayerData
            callSQLViewByWFS(this.geomLayerData.lineParams.service_url, getPolylineRoads, `tbl:${this.geomLayerData.lineParams.target_table};road:`, (data) => {
              if (data && data.features && data.features.length) {
                this.pipeFeatureSearch.polylineRoads = data.features.map(item => {
                  return {
                    value: item.properties.address
                  }
                })
              }
            })
          }, 500)

          // ============================================添加管线图层-BEGIN============================================
          loadFeaturesByWFS(this.geomLayerData.lineParams.service_url, this.geomLayerData.lineParams.layer_prefix + ':' + this.geomLayerData.lineParams.layer_name, this.geomLayerData.lineTableName, (data) => {
            const {polylineLayer, polylineLabelLayer} = initPolylineLayer(data, (e) => {
              // console.log(e.feature.properties)
            })

            this.polylineLayer = polylineLayer
            this.polylineLabelLayer = polylineLabelLayer
          })
          // ============================================添加管线图层-END============================================

          document.addEventListener('initPolylineLayer', () => { // 管线图层加载完成
            setTimeout(() => { // 加载完管线后再加载管点图层
              lineLoaded = true
            }, 50)
          });

          // ============================================添加管点图层-BEGIN============================================
          loadFeaturesByWFS(this.geomLayerData.pointParams.service_url, this.geomLayerData.pointParams.layer_prefix + ':' + this.geomLayerData.pointParams.layer_name, this.geomLayerData.pointTableName, (data) => {
            const {pointLayerList} = initPointLayer(data, (e) => {
              // console.log(e.feature.properties)
            })

            this.pointLayerList = pointLayerList
          })
          // ============================================添加管点图层-END============================================

          document.addEventListener('initPointLayer', () => { // 管点图层加载完成
            setTimeout(() => {
              pointLoaded = true
            }, 50)
          });

          const timerCheckLoaded = setInterval(() => { // 管线管点图层都加载完成后，设置图层树
            if (lineLoaded && pointLoaded) {
              initMapLayerTree(this.layerTreeData, this.polylineLayer, this.polylineLabelLayer, this.pointLayerList, (selectedTreeNodeKeys) => {
                this.$nextTick(() => {
                  // 图层添加到地图场景
                  scene.addLayer(this.polylineLayer);
                  scene.addLayer(this.polylineLabelLayer);
                  this.pointLayerList.forEach(item => scene.addLayer(item.target))

                  // 设置图层管理树默认选中节点
                  this.defaultCheckTreeData = selectedTreeNodeKeys
                  this.layerTreeLoading = false
                  this.$forceUpdate()

                  // 清除定时器
                  clearInterval(timerCheckLoaded)
                })
              })
            }
          }, 50)
        }
      })
    },
    // 获取并设置字典数据
    getAndSetDictDataOptions(dictType) {
      const {serviceUrl, getDictData} = this.geomLayerData
      const viewParams = `dictType:${dictType}`
      callSQLViewByWFS(serviceUrl, getDictData, viewParams, (data) => {
        if (data.features.length) {
          const options = data.features.map(item => {
            return {label: item.properties.dict_label, value: item.properties.dict_label}
          })
          this.dictTypes[dictType] = options
        }
      })
    },
    // 初始化字典数据
    initDictTypeOptions() {
      Object.keys(this.dictTypes).forEach(key => {
        this.getAndSetDictDataOptions(key)
      })
    },
    // GIS分析工具主类型样式
    getActiveMainStyle(mainKey) {
      return {backgroundColor: this.activeToolMain === mainKey ? '#007bea' : '#053c8a'}
    },
    // GIS分析工具子功能样式
    getActiveSubStyle(subKey) {
      return {backgroundColor: this.activeToolSub === subKey ? '#006dc6' : 'transparent'}
    },
    // GIS分析工具子功能点击处理
    handleSubToolClick(subKey) {
      this.activeToolSub = subKey
      this.toolBarContentVisible = true
      this.layerPanelVisible = false
    },
    exportDataToExcel(tableColumns, tableData, fileName) {
      ExportExcel(tableColumns, tableData, fileName)
    },
    // 重置绘制工具及数据
    resetDrawTool(key, drawTool) {
      if (drawTool !== undefined) {
        drawTool.clear();
        drawTool = undefined

        if (key === 1) {
          this.mapDrawPoints = {}
        } else {
          this.mapDrawPolygons = {}
        }
      }
    },
    // 清除地图上绘制物
    clearMapDrawFeatures() {
      this.mapScene.removeAllMarkers()
      this.drawFirePointTool.clear()
      this.drawLeakPointTool.clear()
      if (this.drawPolygonTool) {
        this.drawPolygonTool.clear()
      }
      if (this.drawRectTool) {
        this.drawRectTool.clear()
      }
      if (this.analysisLineLayer) {
        this.analysisLineLayer.clear()
        this.mapScene.removeLayer(this.analysisLineLayer)
        this.analysisLineLayer = undefined
      }
    },
    initAnalysisLineLayer() {
      this.analysisLineLayer = new LineLayer({
        name: 'analysisLineLayer',
        zIndex: 10000
      })
        .source([])
        .shape('line')
        .size(2)
        .color('#1889fd');
      this.mapScene.addLayer(this.analysisLineLayer)
    },
    // 初始化地图点绘制工具
    initDrawPointTool(key) {
      const iconMap = {'fire': 'huozaidian', 'leak': 'baoguan'}
      const pointShape = {shape: iconMap[key], size: 15, color: '#FFFFFF'}

      const drawTool = new DrawPoint(this.mapScene, {
        autoActive: false,
        editable: true,
        multiple: false,
        popup: false,
        maxCount: 1,
        style: {
          point: {
            normal: pointShape,
            hover: pointShape,
            active: pointShape
          },
        },
      });
      drawTool.disable()

      // 监听绘制事件
      drawTool.on(DrawEvent.Change, (pointList) => {
        if (pointList && pointList.length) {
          this.mapDrawPoints[key] = pointList[0]
          this.mouseTipText = '可拖动选点调整位置'
          if (key === 'fire') {
            this.pipeFeatureSearch.fireHydrantForm.coordinate = pointList[0].geometry.coordinates.join(' ')
          } else {
            this.pipeFeatureSearch.leakAnalysisForm.leakPoint = pointList[0].geometry.coordinates
          }
        }
      });

      if (key === 'fire') {
        this.drawFirePointTool = drawTool
      } else {
        this.drawLeakPointTool = drawTool
      }
    },
    // 初始化地图平面绘制工具
    initDrawPolygonTool(key, callback) {
      this.resetDrawTool(2, this.drawPolygonTool)

      this.drawPolygonTool = new DrawPolygon(this.mapScene, {
        autoActive: false,
        editable: true,
        multiple: false,
        popup: false,
        maxCount: 1,
      });
      this.drawPolygonTool.enable()

      // 监听绘制事件
      this.drawPolygonTool.on(DrawEvent.Change, (polygonList) => {
        if (polygonList && polygonList.length) {
          this.mapDrawPolygons[key] = polygonList[0]
          this.mouseTipText = ''
          this.$refs.refMouseTip.setVisible(false)
          this.drawPolygonTool.disable()
          callback(polygonList[0])
        }
      });
    },
    // 初始化地图矩形绘制工具
    initDrawRectTool(key, callback) {
      this.drawRectTool = new DrawRect(this.mapScene, {
        autoActive: false,
        editable: true,
        multiple: false,
        popup: false,
        maxCount: 1,
      });
      this.drawRectTool.enable()

      // 监听绘制事件
      this.drawRectTool.on(DrawEvent.Change, (featureList) => {
        if (featureList && featureList.length) {
          this.mapDrawRects[key] = featureList[0]
          this.mouseTipText = ''
          this.$refs.refMouseTip.setVisible(false)
          this.drawRectTool.disable()
          callback(featureList[0])
        }
      });
    },
    // 在地图上矩形框选并添加单点图标
    checkAndAddCustomMarker(key, polygonData, callback) {
      const points = polygonData.geometry.coordinates.flat()
      const coords = []
      coords.push(points)
      const polygon = turf.polygon(coords);

      const pointsInPolygon = []

      this.pointLayerList.forEach(pointLayer => {
        const pointSourceData = pointLayer.target.getSource().data.dataArray
        pointSourceData.forEach(ps => {
          const point = turf.point(ps.coordinates)
          const flag = turf.booleanPointInPolygon(point, polygon)
          if (flag) {
            pointsInPolygon.push(ps)
          }
        })
      })

      if (pointsInPolygon.length) {
        if (pointsInPolygon.length === 1) {
          const el = document.createElement('label');
          el.className = 'labelclass';
          el.textContent = key === 'start' ? '始' : '终';
          el.style.background = '#fc4e2a';
          el.style.borderColor = '#fc4e2a';
          el.style.color = '#FFFFFF';
          const marker = new Marker({
            element: el,
          }).setLnglat(pointsInPolygon[0].coordinates);
          this.mapScene.addMarker(marker);

          callback(pointsInPolygon[0])

          this.drawRectTool.clear()
          this.drawRectTool.destroy()
        } else {
          this.drawRectTool.clear()
          this.drawRectTool.destroy()
          this.$message.error('只能选择一个管点，请重新选择')
        }
      } else {
        this.drawRectTool.clear()
        this.drawRectTool.destroy()
        this.$message.error('没有选中任何管点，请重新选择')
      }
    },
    // 根据键、类型获取地图绘制点坐标值
    getMapDrawPointValue(key, type) {
      return this.mapDrawPoints[key] ? this.mapDrawPoints[key].geometry.coordinates[type === 'x' ? 0 : 1] : 0
    },
    // 处理图层树节点点击事件
    handleNodeChange(data, checked, indeterminate) {
      // console.log(data, checked)
      if (data.target) {
        if (checked) {
          data.target.show()
        } else {
          data.target.hide()
        }
      }
    },
    // 获取图层树节点图标
    getLayerNodeImage(data) {
      return require(`@/assets/gis-svg/` + data.icon)
    },
    // 添加并地图居中显示要素
    addAndCenterFeature(data, clear = true) {
      if (clear) {
        this.clearMapDrawFeatures()
      }

      const geom = data.transform_geom || data.geom || data.geometry
      const type = geom.type
      const coordinates = geom.coordinates
      if (type === 'Point') {
        const marker = new Marker().setLnglat(coordinates); // 添加进Marker必须设置经纬度才能添加
        this.mapScene.addMarker(marker);
        this.mapScene.setZoomAndCenter(16, coordinates)
      } else if (type === 'MultiLineString') {
        this.initAnalysisLineLayer()

        const jsonData = {
          type: 'FeatureCollection',
          features: [
            {
              type: 'Feature',
              properties: {},
              geometry: {
                type: 'LineString',
                coordinates: [].concat(coordinates[0]),
              },
            },
          ],
        };

        this.analysisLineLayer.setData(jsonData)
        this.analysisLineLayer.show()
        this.mapScene.setZoomAndCenter(16, coordinates[0][0])
      }
    },
    // 分析工具按钮点击处理
    handleToolBarClick(idx) {
      if (idx === 1) {
        this.clearMapDrawFeatures()
      } else if (idx === 2) {
        this.analysisToolPanelVisible = !this.analysisToolPanelVisible
      } else if (idx === 3) {
        if (this.legendPanelVisible) {
          this.legendControl.hide()
          this.legendPanelVisible = false
        } else {
          this.legendControl.show()
          this.legendPanelVisible = true
        }
      } else {
        this.layerPanelVisible = !this.layerPanelVisible
      }
    },
    // 分析表单-道路下拉选择过滤
    queryRoadSearch(queryString, cb) {
      const polylineRoads = this.pipeFeatureSearch.polylineRoads;
      const results = queryString ? polylineRoads.filter(item => item.value.indexOf(queryString) === 0) : polylineRoads;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    // 分析表单重置
    handleFormReset(formName) {
      if (formName === 'locatorForm1') {
        this.pipeFeatureSearch.locatorForm1 = {
          x: null,
          y: null,
        }
        this.mapScene.removeAllMarkers()
      }

      if (formName === 'locatorForm2') {
        this.pipeFeatureSearch.locatorForm2 = {
          road1: null,
          road2: null,
        }
        this.mapScene.removeAllMarkers()
      }

      if (formName === 'locatorForm3') {
        this.pipeFeatureSearch.locatorForm3 = {
          keywords: null,
          tableData: []
        }
        this.mapScene.removeAllMarkers()
        if (this.analysisLineLayer) {
          this.analysisLineLayer.hide()
        }
      }

      if (formName === 'statisticForm1') {
        this.pipeFeatureSearch.statisticForm1 = {
          radius: 50,
          iType: 1,
          tableData: [],
          queryLoading: false,
        }
        this.mapScene.removeAllMarkers()
        if (this.analysisLineLayer) {
          this.analysisLineLayer.hide()
        }
      }

      this.resetForm(formName);
    },
    // 坐标定位
    handleAccurateLocatorClick(btnIdx) {
      switch (btnIdx) {
        case 1: { // 定位
          if (!this.pipeFeatureSearch.locatorForm1.x || !this.pipeFeatureSearch.locatorForm1.y) {
            this.$message.error('请先输入X坐标和Y坐标')
            return
          }

          this.clearMapDrawFeatures()

          const {x, y} = this.pipeFeatureSearch.locatorForm1
          const marker = new Marker({}).setLnglat([x, y])
          this.mapScene.addMarker(marker)
          this.mapScene.panTo([x, y])
          break;
        }
        case 2: { // 重置
          this.handleFormReset('locatorForm1')
          this.clearMapDrawFeatures()
          break;
        }
      }
    },
    // 交叉路口定位
    handleCrossPointLocatorClick(btnIdx, item) {
      switch (btnIdx) {
        case 1: { // 道路1选择
          this.pipeFeatureSearch.locatorForm2.road1 = item.value
          break;
        }
        case 2: { // 道路2选择
          this.pipeFeatureSearch.locatorForm2.road2 = item.value
          break;
        }
        case 3: { // 查询
          if (!this.pipeFeatureSearch.locatorForm2.road1 || !this.pipeFeatureSearch.locatorForm2.road2) {
            this.$message.error('请先选择两条道路')
            return
          }

          this.clearMapDrawFeatures()

          const {serviceUrl, getCrossPoints, lineTableName} = this.geomLayerData
          callSQLViewByWFS(serviceUrl, getCrossPoints, `tbl:${lineTableName};road1:${this.pipeFeatureSearch.locatorForm2.road1};road2:${this.pipeFeatureSearch.locatorForm2.road2}`, (data) => {
            if (data.features.length) {
              this.mapScene.removeAllMarkers()
              data.features.forEach(feature => {
                const marker = new Marker({}).setLnglat(feature.geometry.coordinates)
                this.mapScene.addMarker(marker)
                this.mapScene.panTo(feature.geometry.coordinates)
              })
            } else {
              this.$message.error('您选择的两条道路没有交叉点')
            }
          })
          break;
        }
        case 4: { // 重置
          this.handleFormReset('locatorForm2')
          this.clearMapDrawFeatures()
          break;
        }
      }
    },
    // 模糊定位-查询
    handleVagueLocatorClick(btnIdx, row) {
      switch (btnIdx) {
        case 1: { // 查询
          if (!this.pipeFeatureSearch.locatorForm3.keywords) {
            this.$message.error('请先输入关键字')
            return
          }

          this.clearMapDrawFeatures()

          const {serviceUrl, tenant, getBufferFeature} = this.geomLayerData
          this.pipeFeatureSearch.locatorForm3.tableData = []
          callSQLViewByWFS(serviceUrl, getBufferFeature, `tenant:${tenant};road:${this.pipeFeatureSearch.locatorForm3.keywords};radius:0;iType:0`, (data) => {
            if (data.features.length) {
              const featureData = JSON.parse(data.features[0].properties.qt_nearby_tenant)
              if (featureData && featureData.length) {
                this.pipeFeatureSearch.locatorForm3.tableData = featureData.map(item => {
                  return {
                    id: item.id,
                    name: item.type === 1 ? item.FEATURE : item.ADDRESS,
                    category: item.type === 1 ? '管点' : '管线',
                    origin: item
                  }
                })
              } else {
                this.$message.error('暂无数据')
              }
            }
          })
          break;
        }
        case 2: { // 重置
          this.handleFormReset('locatorForm3')
          this.clearMapDrawFeatures()
          break;
        }
        case 3: { // 行点击回调
          this.addAndCenterFeature(row.origin)
        }
      }
    },
    // 道路缓冲查询
    handleRoadBufferClick(btnIdx, item) {
      switch (btnIdx) {
        case 1: { // 道路选择
          this.pipeFeatureSearch.statisticForm1.road = item.value
          break;
        }
        case 2: { // 更改类型
          this.pipeFeatureSearch.statisticForm1.tableData = []
          break;
        }
        case 3: { // 查询
          if (!this.pipeFeatureSearch.statisticForm1.road) {
            this.$message.error('请先选择道路')
            return
          }

          this.clearMapDrawFeatures()

          const iType = this.pipeFeatureSearch.statisticForm1.iType
          const {serviceUrl, tenant, getBufferFeature} = this.geomLayerData
          this.pipeFeatureSearch.statisticForm1.tableData = []
          this.pipeFeatureSearch.statisticForm1.queryLoading = true
          callSQLViewByWFS(serviceUrl, getBufferFeature, `tenant:${tenant};road:${this.pipeFeatureSearch.statisticForm1.road};radius:${this.pipeFeatureSearch.statisticForm1.radius};iType:${iType}`, (data) => {
            this.pipeFeatureSearch.statisticForm1.queryLoading = false
            if (data.features.length) {
              const featureData = JSON.parse(data.features[0].properties.qt_nearby_tenant)
              if (featureData && featureData.length) {
                const groupData = featureData.groupBy(it => it.type)

                // ===============标记管线===============
                this.initAnalysisLineLayer()

                const jsonData = {
                  type: 'FeatureCollection',
                  features: [],
                };

                groupData[0].forEach(it => {
                  const featureItem = {
                    type: 'Feature',
                    properties: {},
                    geometry: {
                      type: 'LineString',
                      coordinates: [].concat(it.transform_geom.coordinates[0])
                    },
                  }
                  jsonData.features.push(featureItem)
                })

                this.analysisLineLayer.setData(jsonData)
                this.analysisLineLayer.show()
                // ===============标记管线===============

                const targetData = groupData[iType]
                if (targetData && targetData.length) {
                  this.pipeFeatureSearch.statisticForm1.tableData = targetData.map(it => {
                    const ft = it
                    ft.name = it.type === 1 ? it.FEATURE : it.ADDRESS
                    ft.category = it.type === 1 ? it.SCODE : '管线'
                    return ft
                  })
                }
              } else {
                this.$message.error('暂无数据')
              }
            }
          })
          break;
        }
        case 4: { // 重置
          this.handleFormReset('statisticForm1')
          break;
        }
        case 5: { // 导出
          if (!this.pipeFeatureSearch.statisticForm1.tableData.length) {
            this.$message.error('暂无数据')
            return
          }
          const columns = this.pipeFeatureSearch.statisticForm1.iType === 1 ? this.pointTableColumns : this.lineTableColumns
          this.exportDataToExcel(columns, this.pipeFeatureSearch.statisticForm1.tableData, '道路缓冲查询数据')
          break;
        }
        case 6: { // 行点击回调
          this.addAndCenterFeature(item)
          break;
        }
      }
    },
    // 管线要素查询
    handlePipeFeatureQuery(btnIdx, item) {
      switch (btnIdx) {
        case 1: { // 查询
          if (!this.pipeFeatureSearch.value) {
            this.$message.error('请输入字段值')
            return
          }

          this.clearMapDrawFeatures()

          const {serviceUrl, lineTableName, pointTableName, getPipeFeature} = this.geomLayerData
          const searchType = this.pipeFeatureSearch.type
          const tbl = searchType === 'point' ? pointTableName : lineTableName
          const field = searchType === 'point' ? this.pipeFeatureSearch.pointField : this.pipeFeatureSearch.lineField
          const operator = searchType === 'point' ? this.pipeFeatureSearch.pointOperator : this.pipeFeatureSearch.lineOperator
          const viewParams = `tbl:${tbl};FK:${field};OP:${operator};FV:${this.pipeFeatureSearch.value}`

          this.pipeFeatureSearch.pointData = []
          this.pipeFeatureSearch.lineData = []
          callSQLViewByWFS(serviceUrl, getPipeFeature, viewParams, (data) => {
            if (data.features.length) {
              const tableData = data.features.map(fd => {
                return JSON.parse(fd.properties.qt_dynamic_table_json)
              })
              if (searchType === 'point') {
                this.pipeFeatureSearch.pointData = tableData
              } else {
                this.pipeFeatureSearch.lineData = tableData
              }
            } else {
              this.$message.error('暂无数据')
            }
          })
          break;
        }
        case 2: { // 导出
          const data = this.pipeFeatureSearch.type === 'point' ? this.pipeFeatureSearch.pointData : this.pipeFeatureSearch.lineData
          if (!data.length) {
            this.$message.error('暂无数据')
            return
          }
          const columns = this.pipeFeatureSearch.type === 'point' ? this.pointTableColumns : this.lineTableColumns
          this.exportDataToExcel(columns, data, '管线要素查询数据')
          break;
        }
        case 3: { // 行点击回调
          this.addAndCenterFeature(item)
          break;
        }
      }
    },
    // 管线长度查询
    handlePipeLengthQuery(btnIdx) {
      switch (btnIdx) {
        case 1: { // 查询
          if (!this.pipeFeatureSearch.pipeLengthQueryForm.pipeMaterial.length) {
            this.$message.error('请选择管线材质')
            return
          }

          this.clearMapDrawFeatures()

          const {serviceUrl, getPipeLength, lineTableName} = this.geomLayerData
          const DS = this.pipeFeatureSearch.pipeLengthQueryForm.pipeDn.join('\\,') || 0
          const viewParams = `tbl:${lineTableName};MT:${this.pipeFeatureSearch.pipeLengthQueryForm.pipeMaterial.join('\\,')};DS:${DS}`
          this.pipeFeatureSearch.pipeLengthTableData = []
          this.pipeFeatureSearch.pipeLengthQueryLoading = true
          callSQLViewByWFS(serviceUrl, getPipeLength, viewParams, (data) => {
            this.pipeFeatureSearch.pipeLengthQueryLoading = false
            if (data.features.length) {
              const tableData = data.features.map(fd => {
                return fd.properties
              })
              this.pipeFeatureSearch.pipeLengthSpanArray = []
              getSpanArr(tableData, 'material', this.pipeFeatureSearch.pipeLengthSpanArray)
              this.pipeFeatureSearch.pipeLengthTableData = tableData
            }
          })

          break;
        }
        case 2: { // 导出
          if (!this.pipeFeatureSearch.pipeLengthTableData.length) {
            this.$message.error('暂无数据')
            return
          }

          this.exportDataToExcel(this.pipeFeatureSearch.pipeLengthTableColumns, this.pipeFeatureSearch.pipeLengthTableData, '管线长度查询数据')
          break;
        }
      }
    },
    //  区域内管线长度查询
    handlePipeLengthInPolygonQuery(btnIdx) {
      switch (btnIdx) {
        case 1: { // 区域选择
          this.mouseTipText = '请在地图上点选区域'
          this.$refs.refMouseTip.setVisible(true)
          this.initDrawPolygonTool('pipeLength', (data) => {
            const t = data.geometry.coordinates[0].map(item => item.join(' '))
            this.pipeFeatureSearch.pipeLengthInPolygonPoints = t.join('\\,')
          })

          break;
        }
        case 2: { // 查询
          if (!this.pipeFeatureSearch.pipeLengthInPolygonPoints) {
            this.$message.error('请先选择区域')
            return
          }

          const {serviceUrl, getPipeLengthInPolygon, lineTableName} = this.geomLayerData
          const viewParams = `tbl:${lineTableName};coords:${this.pipeFeatureSearch.pipeLengthInPolygonPoints}`
          this.pipeFeatureSearch.pipeLengthInPolygonTableData = []
          this.pipeFeatureSearch.pipeLengthInPolygonQueryLoading = true
          callSQLViewByWFS(serviceUrl, getPipeLengthInPolygon, viewParams, (data) => {
            this.pipeFeatureSearch.pipeLengthInPolygonQueryLoading = false
            if (data.features.length) {
              const tableData = data.features.map(fd => {
                return fd.properties
              })
              this.pipeFeatureSearch.pipeLengthInPolygonSpanArray = []
              getSpanArr(tableData, 'material', this.pipeFeatureSearch.pipeLengthInPolygonSpanArray)
              this.pipeFeatureSearch.pipeLengthInPolygonTableData = tableData
            }
          })

          break;
        }
        case 3: { // 导出
          if (!this.pipeFeatureSearch.pipeLengthInPolygonTableData.length) {
            this.$message.error('暂无数据')
            return
          }

          this.exportDataToExcel(this.pipeFeatureSearch.pipeLengthInPolygonTableColumns, this.pipeFeatureSearch.pipeLengthInPolygonTableData, '区域内管线长度查询数据')
          break;
        }
      }
    },
    // 管线长度查询合并行
    pipeLengthSpanMethod({row, column, rowIndex, columnIndex}) {
      if (columnIndex === 0) {
        const _row = this.pipeFeatureSearch.pipeLengthSpanArray[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 区域内管线长度查询合并行
    pipeLengthInPolygonSpanMethod({row, column, rowIndex, columnIndex}) {
      if (columnIndex === 0) {
        const _row = this.pipeFeatureSearch.pipeLengthInPolygonSpanArray[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 设施数量查询
    handlePointTypeCountQuery(btnIdx) {
      switch (btnIdx) {
        case 1: { // 查询
          if (!this.pipeFeatureSearch.pointTypeCountQueryForm.pointType.length) {
            this.$message.error('请选择设施类型')
            return
          }

          this.clearMapDrawFeatures()

          const {serviceUrl, getFacilityCountByType, pointTableName} = this.geomLayerData
          const viewParams = `tbl:${pointTableName};SC:${this.pipeFeatureSearch.pointTypeCountQueryForm.pointType.join('\\,')}`
          this.pipeFeatureSearch.pointTypeQueryLoading = true
          this.pipeFeatureSearch.pointTypeCountTableData = []
          callSQLViewByWFS(serviceUrl, getFacilityCountByType, viewParams, (data) => {
            this.pipeFeatureSearch.pointTypeQueryLoading = false
            if (data.features.length) {
              this.pipeFeatureSearch.pointTypeCountTableData = data.features.map(fd => {
                return fd.properties
              })
            } else {
              this.$message.error('暂无数据')
            }
          })

          break;
        }
        case 2: { // 导出
          if (!this.pipeFeatureSearch.pointTypeCountTableData.length) {
            this.$message.error('暂无数据')
            return
          }

          this.exportDataToExcel(this.pipeFeatureSearch.pointTypeCountTableColumns, this.pipeFeatureSearch.pointTypeCountTableData, '设施数量查询数据')
          break;
        }
      }
    },
    // 区域内设施数量查询
    handlePointTypeCountInPolygonQuery(btnIdx) {
      switch (btnIdx) {
        case 1: { // 查询
          this.mouseTipText = '请在地图上选择区域'
          this.$refs.refMouseTip.setVisible(true)
          this.initDrawPolygonTool('pointType', (data) => {
            const t = data.geometry.coordinates[0].map(item => item.join(' '))
            this.pipeFeatureSearch.pointTypeInPolygonPoints = t.join('\\,')
          })

          break;
        }
        case 2: { // 查询
          if (!this.pipeFeatureSearch.pointTypeInPolygonPoints) {
            this.$message.error('请先选择区域')
            return
          }

          const {serviceUrl, getFacilityCountByTypeInPolygon, pointTableName} = this.geomLayerData
          const viewParams = `tbl:${pointTableName};coords:${this.pipeFeatureSearch.pointTypeInPolygonPoints}`
          this.pipeFeatureSearch.pointTypeCountInPolygonTableData = []
          this.pipeFeatureSearch.pointTypeInPolygonQueryLoading = true
          callSQLViewByWFS(serviceUrl, getFacilityCountByTypeInPolygon, viewParams, (data) => {
            this.pipeFeatureSearch.pointTypeInPolygonQueryLoading = false
            if (data.features.length) {
              this.pipeFeatureSearch.pointTypeCountInPolygonTableData = data.features.map(fd => {
                return fd.properties
              })
            }
          })

          break;
        }
        case 3: { // 导出
          if (!this.pipeFeatureSearch.pointTypeCountInPolygonTableData.length) {
            this.$message.error('暂无数据')
            return
          }

          this.exportDataToExcel(this.pipeFeatureSearch.pointTypeCountTableColumns, this.pipeFeatureSearch.pointTypeCountInPolygonTableData, '区域内设施数量查询数据')
          break;
        }
      }
    },
    // 关阀预案分析
    handleLeakAnalysisClick(btnIdx, item) {
      switch (btnIdx) {
        case 1: { // 爆管选点
          this.mouseTipText = '请在管线上选择爆管点'
          this.$refs.refMouseTip.setVisible(true)
          this.clearMapDrawFeatures()
          this.drawLeakPointTool.enable()
          break;
        }
        case 2: { // 爆管分析
          if (!this.pipeFeatureSearch.leakAnalysisForm.leakPoint) {
            this.$message.error('请在管线上选择爆管点')
            return
          }

          const {serviceUrl, getLeakClosestValve, tenant} = this.geomLayerData
          const point = this.pipeFeatureSearch.leakAnalysisForm.leakPoint
          const viewParams = `tenant:${tenant};lon:${point[0]};lat:${point[1]}`
          this.pipeFeatureSearch.leakAnalysisForm.tableData = []
          this.pipeFeatureSearch.leakAnalysisForm.queryLoading = true
          callSQLViewByWFS(serviceUrl, getLeakClosestValve, viewParams, (data) => {
            this.pipeFeatureSearch.leakAnalysisForm.queryLoading = false
            if (data.features.length) {
              this.pipeFeatureSearch.leakAnalysisForm.tableData = data.features.filter(it => it.properties.v_type === '1').map(fd => {
                return JSON.parse(fd.properties.v_res)
              })

              if (this.pipeFeatureSearch.leakAnalysisForm.tableData.length) {
                this.mapScene.removeAllMarkers()
                this.pipeFeatureSearch.leakAnalysisForm.tableData.forEach(pt => {
                  const marker = new Marker().setLnglat(pt.geom.coordinates); // 添加进Marker必须设置经纬度才能添加
                  this.mapScene.addMarker(marker);
                })
              } else {
                this.$message.error('爆管点附近无消防设施')
              }

              // ===============标记管线===============
              if (this.analysisLineLayer) {
                this.mapScene.removeLayer(this.analysisLineLayer)
                this.analysisLineLayer = undefined
              }
              const jsonData = {
                type: 'FeatureCollection',
                features: [],
              };

              data.features.filter(it => it.properties.v_type === '2').forEach(item => {
                const pipe = JSON.parse(item.properties.v_res)
                const featureItem = {
                  type: 'Feature',
                  properties: {},
                  geometry: {
                    type: 'LineString',
                    coordinates: pipe.geom.coordinates
                  },
                }
                jsonData.features.push(featureItem)
              })

              this.analysisLineLayer = new LineLayer()
                .source(jsonData)
                .shape('line')
                .size(2)
                .color('#1889fd');
              this.mapScene.addLayer(this.analysisLineLayer)
              // ===============标记管线===============
            } else {
              this.$message.error('爆管点附近无消防设施')
            }
          })

          break;
        }
        case 3: { // 导出
          if (!this.pipeFeatureSearch.leakAnalysisForm.tableData.length) {
            this.$message.error('暂无数据')
            return
          }

          this.exportDataToExcel(this.pipeFeatureSearch.pointTableColumns, this.pipeFeatureSearch.leakAnalysisForm.tableData, '关阀预案分析数据')
          break;
        }
        case 4: { // 行点击回调
          this.addAndCenterFeature(item)
          break;
        }
      }
    },
    // 火灾分析
    handleFeatureFireHydrantQueryClick(btnIdx, item) {
      switch (btnIdx) {
        case 1: { // 火灾选点
          this.mouseTipText = '请选定火灾点'
          this.$refs.refMouseTip.setVisible(true)
          this.clearMapDrawFeatures()
          this.drawFirePointTool.enable()
          break;
        }
        case 2: { // 查询消防栓
          if (!this.pipeFeatureSearch.fireHydrantForm.coordinate) {
            this.$message.error('请先选定火灾点')
            return
          }

          const {serviceUrl, getFireHydrant, pointTableName} = this.geomLayerData
          const viewParams = `tbl:${pointTableName};coord:${this.pipeFeatureSearch.fireHydrantForm.coordinate};distance:${this.pipeFeatureSearch.fireHydrantForm.bufferRange}`
          this.pipeFeatureSearch.fireHydrantForm.fireHydrantTableData = []
          this.pipeFeatureSearch.fireHydrantForm.fireHydrantLoading = true
          callSQLViewByWFS(serviceUrl, getFireHydrant, viewParams, (data) => {
            this.pipeFeatureSearch.fireHydrantForm.fireHydrantLoading = false
            if (data.features.length) {
              this.pipeFeatureSearch.fireHydrantForm.fireHydrantTableData = data.features.map(item => {
                return {...item.properties, geom: item.geometry}
              })
            } else {
              this.$message.error('暂无数据')
            }
          })

          break;
        }
        case 3: { // 导出
          if (!this.pipeFeatureSearch.fireHydrantForm.fireHydrantTableData.length) {
            this.$message.error('暂无数据')
            return
          }

          this.exportDataToExcel(this.pipeFeatureSearch.fireHydrantForm.fireHydrantTableColumns, this.pipeFeatureSearch.fireHydrantForm.fireHydrantTableData, '火灾分析消防栓数据')
          break;
        }
        case 4: { // 行点击回调
          this.addAndCenterFeature(item, false)
          break;
        }
      }
    },
    // 预警分析查询
    handleFeatureAlarmQueryClick(btnIdx) {
      switch (btnIdx) {
        case 1: { // 查询
          this.clearMapDrawFeatures()

          const {serviceUrl, getFacilitiesByWarningYears, pointTableName, lineTableName} = this.geomLayerData
          const tbl = this.pipeFeatureSearch.featureAlarmQueryForm.featureType === 'line' ? lineTableName : pointTableName
          const scode = this.pipeFeatureSearch.featureAlarmQueryForm.featureType === 'line' ? '管线' : this.pipeFeatureSearch.featureAlarmQueryForm.featureType === 'point' ? '管点' : this.pipeFeatureSearch.featureAlarmQueryForm.featureType
          const viewParams = `tbl:${tbl};SC:${scode};ST:${this.pipeFeatureSearch.featureAlarmQueryForm.alarmType};year:${this.pipeFeatureSearch.featureAlarmQueryForm.featureYears};month:6`
          this.pipeFeatureSearch.featureAlarmQueryLoading = true
          this.pipeFeatureSearch.featureAlarmLineTableData = []
          this.pipeFeatureSearch.featureAlarmPointTableData = []
          callSQLViewByWFS(serviceUrl, getFacilitiesByWarningYears, viewParams, (data) => {
            this.pipeFeatureSearch.featureAlarmQueryLoading = false
            if (data.features.length) {
              if (scode === '管线') {
                this.pipeFeatureSearch.featureAlarmLineTableData = data.features.map(item => {
                  return JSON.parse(item.properties.qt_find_facilities_by_warning_years)
                })
              } else {
                this.pipeFeatureSearch.featureAlarmPointTableData = data.features.map(item => {
                  return JSON.parse(item.properties.qt_find_facilities_by_warning_years)
                })
              }
            } else {
              this.$message.error('暂无数据')
            }
          })

          break;
        }
        case 2: { // 导出
          const data = this.pipeFeatureSearch.featureAlarmQueryForm.featureType === 'line' ? this.pipeFeatureSearch.featureAlarmLineTableData : this.pipeFeatureSearch.featureAlarmPointTableData
          if (!data.length) {
            this.$message.error('暂无数据')
            return
          }
          const columns = this.pipeFeatureSearch.featureAlarmQueryForm.featureType === 'line' ? this.lineTableColumns : this.pointTableColumns
          this.exportDataToExcel(columns, data, '预警分析查询数据')
          break;
        }
        case 3: { // 行点击回调
          this.addAndCenterFeature(item)
          break;
        }
      }
    },
    // 连通性分析
    handleLinkAnalysis(btnIdx) {
      switch (btnIdx) {
        case 1: {
          this.mouseTipText = '请在地图上选择区域'
          this.$refs.refMouseTip.setVisible(true)
          this.clearMapDrawFeatures()
          this.initDrawRectTool('start', (data) => {
            this.checkAndAddCustomMarker('start', data, (target) => {
              this.pipeFeatureSearch.linkAnalysisResult.start = target
              this.polylineLayer.hide()
              this.polylineLayer.show()
            })
          })
          break;
        }
        case 2: {
          this.mouseTipText = '请在地图上选择区域'
          this.$refs.refMouseTip.setVisible(true)
          this.initDrawRectTool('end', (data) => {
            this.checkAndAddCustomMarker('end', data, (target) => {
              this.pipeFeatureSearch.linkAnalysisResult.end = target
              this.polylineLayer.hide()
              this.polylineLayer.show()
            })
          })
          break;
        }
        case 3: {
          if (!this.pipeFeatureSearch.linkAnalysisResult.start.EXP_NO || !this.pipeFeatureSearch.linkAnalysisResult.end.EXP_NO) {
            this.$message.error('请选择起点和终点')
            return
          }

          const {serviceUrl, tenant, getAnalysisConnect} = this.geomLayerData
          const fp = this.pipeFeatureSearch.linkAnalysisResult.start.id
          const sp = this.pipeFeatureSearch.linkAnalysisResult.end.id
          const viewParams = `tenant:${tenant};fp:${fp};sp:${sp};`
          callSQLViewByWFS(serviceUrl, getAnalysisConnect, viewParams, (data) => {
            if (data.features.length) {
              this.analysisLineLayer = new LineLayer()
                .source(data)
                .shape('line')
                .size(2)
                .color('#1889fd');
              this.mapScene.addLayer(this.analysisLineLayer)
              this.pipeFeatureSearch.linkAnalysisResult.result = '连通'
            } else {
              this.pipeFeatureSearch.linkAnalysisResult.result = '不连通'
            }
            this.pipeFeatureSearch.linkAnalysisResult.visible = true
          })
          break;
        }
        case 4: {
          break;
        }
        case 5: {
          break;
        }
      }
    },
    // 高程差分析
    handleAltitudeAnalysis(btnIdx) {
      switch (btnIdx) {
        case 1: {
          this.mouseTipText = '请在地图上选择区域'
          this.$refs.refMouseTip.setVisible(true)
          this.clearMapDrawFeatures()
          this.pipeFeatureSearch.altitudeResult.start = {}
          this.pipeFeatureSearch.altitudeResult.end = {}
          this.pipeFeatureSearch.altitudeResult.visible = false
          this.pipeFeatureSearch.altitudeResult.result = ''

          this.initDrawRectTool('start', (data) => {
            this.checkAndAddCustomMarker('start', data, (target) => {
              this.pipeFeatureSearch.altitudeResult.start = target
            })
          })
          break;
        }
        case 2: {
          this.mouseTipText = '请在地图上选择区域'
          this.$refs.refMouseTip.setVisible(true)
          this.initDrawRectTool('end', (data) => {
            this.checkAndAddCustomMarker('end', data, (target) => {
              this.pipeFeatureSearch.altitudeResult.end = target
            })
          })
          break;
        }
        case 3: {
          if (!this.pipeFeatureSearch.altitudeResult.start.EXP_NO || !this.pipeFeatureSearch.altitudeResult.end.EXP_NO) {
            this.$message.error('请选择起点和终点')
            return
          }

          const startPoint = {}, endPoint = {}
          startPoint.name = this.pipeFeatureSearch.altitudeResult.start.EXP_NO
          startPoint.h = this.pipeFeatureSearch.altitudeResult.start.H
          endPoint.name = this.pipeFeatureSearch.altitudeResult.end.EXP_NO
          endPoint.h = this.pipeFeatureSearch.altitudeResult.end.H

          this.pipeFeatureSearch.altitudeResult.visible = true
          this.pipeFeatureSearch.altitudeResult.result = Math.abs((startPoint.h - endPoint.h)).toFixed(2)
          this.drawAltitudeRect(startPoint, endPoint)

          break;
        }
      }
    },
    // 绘制高程差图表
    drawAltitudeRect(startPoint, endPoint) {
      let x1 = 100
      let ty1 = 30
      let tx2 = 30
      let ty3 = 180
      if (Number(endPoint.h) > Number(startPoint.h)) {
        x1 = x1 + 400
        ty1 = ty1 + 150
        tx2 = tx2 + 480
        ty3 = ty3 - 150
      }

      let canvas = this.$refs.altitudeCanvas
      let ctx = canvas.getContext('2d')
      ctx.clearRect(0, 0, 600, 200)

      ctx.beginPath()
      ctx.fillStyle = '#F9A520'
      ctx.moveTo(x1, 50) // 第一个点坐标
      ctx.lineTo(500, 150) // 顺时针，第二个点坐标
      ctx.lineTo(100, 150) // 顺时针，第三个点坐标
      ctx.fill() // connect and fill

      ctx.font = '12px bold 黑体'

      ctx.beginPath()
      ctx.fillStyle = '#000'
      ctx.fillText('起点：' + startPoint.name + '，高程:' + startPoint.h, 60, ty1)

      ctx.beginPath()
      ctx.fillStyle = '#000'
      ctx.fillText('高程差:' + (Number(endPoint.h) > Number(startPoint.h) ? (endPoint.h - startPoint.h).toFixed(2) : (startPoint.h - endPoint.h).toFixed(2)), tx2, 100)

      ctx.beginPath()
      ctx.fillStyle = '#000'
      ctx.fillText('终点：' + endPoint.name + '，高程:' + endPoint.h, 420, ty3)
    },
    // 文件管理
    handleFeatureFileManage(btnIdx, node) {
      switch (btnIdx) {
        case 1: {
          this.featureTreeData = []
          this.featureFileUpload.treeNode = null
          this.featureFileUpload.tbl = null
          this.featureFileUpload.id = null
          this.featureFileUpload.type = null
          this.mapScene.removeAllMarkers()
          if (this.analysisLineLayer) {
            this.analysisLineLayer.hide()
          }

          this.initDrawRectTool('fileManage', (data) => {
            this.initAnalysisLineLayer()
            const points = data.geometry.coordinates.flat()
            const coords = []
            coords.push(points)
            const polygon = turf.polygon(coords);

            const pointsInPolygon = []
            this.pointLayerList.forEach(pointLayer => {
              const pointSourceData = pointLayer.target.getSource().data.dataArray
              pointSourceData.forEach(ps => {
                const point = turf.point(ps.coordinates)
                const flag = turf.booleanPointInPolygon(point, polygon)
                if (flag) {
                  pointsInPolygon.push(ps)
                }
              })
            })

            const linesIntersectsPolygon = []
            const lineSourceData = this.polylineLayer.getSource().data.dataArray
            lineSourceData.forEach(ls => {
              const line = turf.lineString(ls.coordinates)
              const flag = turf.booleanIntersects(line, polygon)
              if (flag) {
                linesIntersectsPolygon.push(ls)
              }
            })

            const pointTreeData = []
            pointsInPolygon.forEach(ps => {
              pointTreeData.push({
                id: ps.id,
                type: 1,
                label: ps.EXP_NO
              })
              const coordinates = ps.coordinates
              const marker = new Marker().setLnglat(coordinates); // 添加进Marker必须设置经纬度才能添加
              this.mapScene.addMarker(marker);
            })

            const jsonData = {
              type: 'FeatureCollection',
              features: [],
            };
            const lineTreeData = []
            linesIntersectsPolygon.forEach(ps => {
              lineTreeData.push({
                id: ps.id,
                type: 2,
                // label: ps.properties.S_POINT + '-' + ps.properties.E_POINT
                label: ps.S_POINT + '-' + ps.E_POINT
              })
              // const coordinates = ps.geometry.coordinates
              const coordinates = ps.coordinates
              const feature = {
                type: 'Feature',
                properties: {},
                geometry: {
                  type: 'LineString',
                  coordinates: coordinates,
                },
              }
              jsonData.features.push(feature)
            })

            this.analysisLineLayer.setData(jsonData)
            this.analysisLineLayer.show()

            if (pointTreeData.length) {
              this.featureTreeData.push({
                id: '0',
                label: '管点',
                children: pointTreeData,
                disabled: true
              })
            }

            if (lineTreeData.length) {
              this.featureTreeData.push({
                id: '1',
                label: '管线',
                children: lineTreeData,
                disabled: true
              })
            }
          })

          break;
        }
        case 2: {
          if (!this.featureFileUpload.treeNode) {
            this.$message.error('请先选择要素节点')
            return
          }
          this.featureFileUpload.open = true;
          break;
        }
        case 3: {
          this.featureFileUpload.treeNode = node
          this.featureFileUpload.tbl = node.type === 1 ? this.geomLayerData.pointTableName : this.geomLayerData.lineTableName
          this.featureFileUpload.id = node.id
          this.featureFileUpload.type = node.type
          this.loadOssFiles()
          break;
        }
        case 4: {
          const params = {
            fileName: node.file_name,
            originalName: node.original_name
          }

          this.downloadOssFile(`${process.env.VUE_APP_BASE_API}/qtgis/pgedit/downloadOss?fileName=${params.fileName}&originalName=${params.originalName}`)
          break;
        }
        case 5: {
          this.$confirm('确定要删除该文件吗？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            const data = {
              id: node.id,
              fileName: node.file_name
            }
            removeOss(data).then(res => {
              if (res.code === 200) {
                this.$message.success(res.msg)
                this.loadOssFiles()
              } else {
                this.$message.error(res.msg)
              }
            })
          }).catch(() => {
          });

          break;
        }
      }
    },
    loadOssFiles() {
      const params = {
        tbl: this.featureFileUpload.treeNode.type === 1 ? this.geomLayerData.pointTableName : this.geomLayerData.lineTableName,
        id: this.featureFileUpload.treeNode.id
      }
      this.featureFileData = []
      this.featureFileDataLoading = true
      getOssRecords(params).then(res => {
        if (res.code === 200) {
          this.featureFileData = res.data
          this.featureFileDataLoading = false
        }
      })
    },
    downloadOssFile(url) {
      let downloadLoadingInstance = Loading.service({
        text: "正在下载数据，请稍候",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      })
      axios({
        method: 'get',
        url: url,
        responseType: 'blob',
        headers: {'Authorization': 'Bearer ' + getToken()}
      }).then((res) => {
        const isBlob = blobValidate(res.data);
        if (isBlob) {
          const blob = new Blob([res.data], {type: 'application/octet-stream'})
          saveAs(blob, decodeURIComponent(res.headers['download-filename']))
        } else {
          this.printErrMsg(res.data);
        }
        downloadLoadingInstance.close();
      }).catch((r) => {
        console.error(r)
        Message.error('下载文件出现错误，请联系管理员！')
        downloadLoadingInstance.close();
      })
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.featureFileUpload.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.featureFileUpload.open = false;
      this.featureFileUpload.isUploading = false;
      this.$refs.refFileUpload.clearFiles();
      this.$alert("上传成功");
      setTimeout(() => this.loadOssFiles(), 1000)
    },
    // 提交上传文件
    submitFileForm() {
      this.$refs.refFileUpload.submit();
    },
  }
  ,
  created() {
    this.screenHeight = document.body.clientHeight
  }
  ,
  computed: {
    getAvailableHeight() {
      return {height: (this.screenHeight - 70) + 'px'}
    }
    ,
    // 管线长度合计
    getAllPipeLength() {
      const length = sumArray(this.pipeFeatureSearch.pipeLengthTableData.map(item => item.total_length))
      // return length < 1000 ? length + '米' : (length / 1000.0).toFixed(2) + '公里'
      return length.toFixed(2) + '米'
    }
    ,
    // 区域内管线长度合计
    getAllPipeLengthInPolygon() {
      const length = sumArray(this.pipeFeatureSearch.pipeLengthInPolygonTableData.map(item => item.total_length))
      // return length < 1000 ? length + '米' : (length / 1000.0).toFixed(2) + '公里'
      return length.toFixed(2) + '米'
    }
    ,
    // 设施数量合计
    getPointTypeCount() {
      return sumArray(this.pipeFeatureSearch.pointTypeCountTableData.map(item => item.facility_count))
    }
    ,
    // 设施数量合计
    getPointTypeCountInPolygon() {
      return sumArray(this.pipeFeatureSearch.pointTypeCountInPolygonTableData.map(item => item.facility_count))
    }
    ,
    // 获取分析操作内容面板标题
    getToolBarContentTitle() {
      const toolOptions = this.analysisToolOptions.map(item => item.tools)
      const target = toolOptions.flat().filter(item => item.key === this.activeToolSub)
      if (target && target.length === 1) {
        return target[0].name
      }
      return ''
    }
  }
  ,
}
</script>

<style lang="scss" scoped>
.control-button-panel {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1000;
  display: flex;
  justify-content: space-between;
}

.analysis-layer-panel {
  position: absolute;
  bottom: 8px;
  right: 8px;
  height: calc(100% - 50px);
  z-index: 1000;
  color: #FFFFFF;
}

.analysis-tool-panel {
  position: absolute;
  bottom: 26%;
  left: 8px;
  z-index: 1000;
  display: flex;
  justify-content: space-between;

  .tool-box {
    height: 472px;
    border: 1px solid #316bae;
    text-align: center;
    background-color: #032657;
    color: #FFFFFF;

    .tool-box-title {
      width: 180px;
      height: 40px;
      line-height: 40px;
      background-color: #053c8a;
      font-size: 18px;
    }

    .tool-box-item {
      margin: 10px;

      .tool-box-item-title {
        height: 40px;
        line-height: 40px;
        font-size: 16px;
        cursor: pointer;
      }

      .tool-box-item-content {
        background-color: #023d7e;
        padding: 5px;
        font-size: 14px;

        .tool-box-item-tool {
          margin: 5px;
          padding: 5px 0;
          cursor: pointer;
        }
      }
    }
  }
}

.analysis-content-panel {
  position: absolute;
  top: 45px;
  right: 8px;
  z-index: 1000;
  background-color: #FFFFFF;

  .analysis-content-title {
    background-color: #1890ff;
    padding: 5px 10px;
    color: #FFFFFF;
    display: flex;
    justify-content: space-between;
  }
}

.link-analysis-box {
  width: 201px;
  height: 200px;
  margin: 0 auto;
  text-align: center;
  background-image: url("../../../../assets/leakage/isLinked.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-position: 50% 50%;

  &-item {
    color: red;
    font-size: 22px;
    font-weight: bold;
    transform: rotate(346deg);
    padding-top: 90px;
    margin-left: -20px;
  }
}

::v-deep .el-scrollbar__wrap {
  overflow-x: hidden;
}

::v-deep .el-form-item {
  margin-bottom: 15px !important;
}

::v-deep .labelclass {
  position: absolute;
  display: inline;
  cursor: pointer;
  background: #ffe478;
  border: solid 2px #fff;
  padding: 4px;
  white-space: nowrap;
  font: 700 14px / 18px arial, sans-serif;
  color: #fff;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  line-height: 20px;
  text-align: center;
  user-select: none;
}
</style>
